package com.jijunpeng.javafx.cipher.controller;

import com.alibaba.fastjson.JSONObject;
import com.jijunpeng.javafx.cipher.common.DialogUtil;
import com.jijunpeng.javafx.cipher.controller.api.BaseController;
import com.jijunpeng.javafx.cipher.persistence.PersistenceJson;
import javafx.beans.value.ChangeListener;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.Pane;
import lombok.extern.slf4j.Slf4j;
import lombok.val;

import java.security.SecureRandom;

/**
 * @author Ji Junpeng
 * @date 2019-12-10 00:06
 */
@Slf4j
@PersistenceJson(path = "$.main_inner_$random")
public class RandomController extends BaseController {
    @FXML
    private Pane randomRootPane;
    @FXML
    @PersistenceJson(path = "numberCb", field = "selected", getter = "isSelected")
    private CheckBox numberCb;
    @FXML
    @PersistenceJson(path = "lowerLetterCb", field = "selected", getter = "isSelected")
    private CheckBox lowerLetterCb;
    @FXML
    @PersistenceJson(path = "upperLetterCb", field = "selected", getter = "isSelected")
    private CheckBox upperLetterCb;
    @FXML
    @PersistenceJson(path = "specialCharCb", field = "selected", getter = "isSelected")
    private CheckBox specialCharCb;
    @FXML
    @PersistenceJson(path = "excludeSpaceCb", field = "selected", getter = "isSelected")
    private CheckBox excludeSpaceCb;
    @FXML
    @PersistenceJson(path = "randomStringLengthTextField", field = "text")
    private TextField randomStringLengthTextField;
    @FXML
    @PersistenceJson(path = "randomStringTextArea", field = "text")
    private TextArea randomStringTextArea;
    @FXML
    private Button genRandomStringBtn;
    @FXML
    @PersistenceJson(path = "excludeCharsTextField", field = "text")
    private TextField excludeCharsTextField;

    @Override
    protected void initViewData() {
        super.initViewData();
        ChangeListener<Boolean> randomStringBtnStatusListener = (observable, oldValue, newValue) -> genRandomStringBtn.setDisable(!numberCb.isSelected()
                && !lowerLetterCb.isSelected()
                && !upperLetterCb.isSelected()
                && !specialCharCb.isSelected());
        numberCb.selectedProperty().addListener(randomStringBtnStatusListener);
        lowerLetterCb.selectedProperty().addListener(randomStringBtnStatusListener);
        upperLetterCb.selectedProperty().addListener(randomStringBtnStatusListener);
        specialCharCb.selectedProperty().addListener(randomStringBtnStatusListener);

        randomStringLengthTextField.textProperty().addListener((observable, oldValue, newValue) -> {
            try {
                val anInt = Integer.parseInt(newValue);
                genRandomStringBtn.setDisable(anInt <= 0);
            } catch (NumberFormatException e) {
                randomStringLengthTextField.requestFocus();
                DialogUtil.showError(randomRootPane, "长度错误", "随机字符串长度错误");
            }
        });
    }

    @Override
    protected Pane getRootPane() {
        return randomRootPane;
    }

    @Override
    protected void initPersistedValue(JSONObject persistenceJson) throws IllegalAccessException {
        super.initPersistedValue(persistenceJson);
    }

    @Override
    public JSONObject persistWidgets() throws IllegalAccessException {
        return super.persistWidgets();
    }

    @FXML
    private void genRandomString(ActionEvent actionEvent) {
        val random = new SecureRandom();
        int length = Integer.parseInt(randomStringLengthTextField.getText());
        String source = "";
        if (numberCb.isSelected()) {
            source += "0123456789";
        }
        if (lowerLetterCb.isSelected()) {
            source += "abcdefghijklmnopqrstuvwxyz";
        }
        if (upperLetterCb.isSelected()) {
            source += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        }
        if (specialCharCb.isSelected()) {
            source += " !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";
        }
        if (excludeSpaceCb.isSelected()) {
            source = source.replace(" ", "");
        }
        String excludeChars = excludeCharsTextField.getText();
        if (!excludeChars.isEmpty()) {
            for (char excludeChar : excludeChars.toCharArray()) {
                if (excludeChar == ' ') {
                    continue;
                }
                source = source.replace(String.valueOf(excludeChar), "");
            }
        }
        char[] enableChars = source.toCharArray();
        StringBuilder randomSb = new StringBuilder();


        for (int i = 0; i < length; i++) {
            int index = random.nextInt(enableChars.length);
            char selectChar = enableChars[index];
            randomSb.append(selectChar);
        }
        randomStringTextArea.setText(randomSb.toString());
    }
}
